package service;

import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.zip.GZIPInputStream;

import org.apache.tools.tar.*;
import org.apache.tools.tar.*;

public class TarService {

	public static String TEMP_UNTAR_LOCATION = "temp";
	
	/**
	 * Use this method after Untarring something...  Cleans up the left
	 * over directory.
	 */
	public static void cleanUpTemp(){
		File tempDir = new File(TEMP_UNTAR_LOCATION);
		delete(tempDir);
	}
	
	/*
	 * Recursive deletion.  Careful with this one, will delete everything
	 * in directory for good.
	 */
	private static void delete(File dir){
		if(dir.isFile()){
			dir.delete();
		}
		else if(dir.isDirectory()){
			File[] fileList = dir.listFiles();
			for(File file : fileList){
				delete(file);
			}
		}
	}
	
	/**
	 * Untars the zipped tar archive at the public static location field.
	 * 
	 * untars to TEMP_UNTAR_LOCATION
	 * 
	 * @param fileLocation
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public static void unTarGZ(String fileLocation) throws FileNotFoundException, IOException{
		GZIPInputStream is = gUnzip(fileLocation);
		unTar(is);
	}

	private static GZIPInputStream gUnzip(String fileLocation)
			throws FileNotFoundException, IOException {
		File zippedFile = new File(fileLocation);
		GZIPInputStream is = new GZIPInputStream(
				new FileInputStream(zippedFile));
		
		return is;
	}

	private static void unTar(GZIPInputStream is) throws IOException {

		TarInputStream tis = new TarInputStream(is);
		TarEntry tar;

		while ((tar = tis.getNextEntry()) != null) {
			if (tar.isDirectory()){
				continue;
			}
			else {
				String[] chop = tar.getName().split(".log.");
				File f = new File(TEMP_UNTAR_LOCATION+ "//" + chop[chop.length-1]);
				boolean p = (new File(TEMP_UNTAR_LOCATION)).mkdir();
				System.out.println(p);
				
				FileOutputStream fos = new FileOutputStream(f);
				InputStream tes = new TarEntryStream(tis, tar.getSize());
				byte[] buffer = new byte[1024];
				int cur = 0;
				int read = 1024;
				while ((read = tes.read(buffer, cur, cur + read)) != -1) {
					fos.write(buffer);
				}
				fos.close();				
			}
		}
		tis.close();
	}
}

/**
 * Retrieved most of this class from the internet.
 * @author Brad
 */
class TarEntryStream extends InputStream {
	final long maxSize;
	final InputStream base;
	long alreadyRead;

	public TarEntryStream(InputStream in, long maxSize) {
		this.maxSize = maxSize;
		alreadyRead = 0;
		base = in;
	}

	@Override
	public synchronized int available() throws IOException {
		long a = base.available();
		if (alreadyRead + a > maxSize)
			a = maxSize - alreadyRead;
		return (int) a;
	}

	@Override
	public synchronized int read() throws IOException {
		if (alreadyRead >= maxSize)
			throw new EOFException();
		int r = base.read();
		alreadyRead += 1;
		return r;
	}

	@Override
	public synchronized int read(byte[] b) throws IOException {
		return read(b, 0, b.length);
	}

	@Override
	public synchronized int read(byte[] b, int off, int len) throws IOException {
		if (alreadyRead >= maxSize)
			return -1;
		if (alreadyRead + len > maxSize)
			len = (int) (maxSize - alreadyRead);
		int r = base.read(b, off, len);
		alreadyRead += r;
		return r;
	}

	@Override
	public synchronized long skip(long n) throws IOException {
		if (n < 0)
			return 0;
		if (alreadyRead >= maxSize)
			return 0;
		if (alreadyRead + n > maxSize)
			n = maxSize - alreadyRead;
		long r = base.skip(n);
		alreadyRead += r;
		return r;
	}

}
